断断续续的在看 Flask 的源码, 记录下一些有意思的现象。一些来自网络,一些是自己发现。
jsonify 和 json.dumps 的区别
Content-Type有区别: 使用 jsonify 时响应的 Content-Type 字段值为 application/json,而使用 json.dumps 时该字段值为 text/html
jsonify 输出的数据量更小,因为非 debug 模式或者未设置 JSONIFY_PRETTYPRINT_REGULAR 会使返回更加紧凑。
在 Debug 模式下初始化两次
1 | from app import app |
输出
1 | 1492742262.002537 |
这将导致我们的某些需要在初始化时执行的方法被执行2次,这显然不是我们需要的结果。出现这样的问题的原因是在开启 Debug 模式的时候,Werkzeug 默认会 启动一个额外的进程 来监控文件变化以方便重启进程。
要解决这个启动两次的问题,有这样几种方法:
1.取消自动重启
1 | app.run(port=5000, debug=True, use_reloader=False) |
2.判断 Werkzeug 主进程是否执行
在 restart_with_reloader function 中,我们可以看到在新进程启动前,环境变量 WEAKZEUG_RUN_MAIN
被置为 'true'
1
new_environ['WERKZEUG_RUN_MAIN'] = 'true'
1 | if __name__ == '__main__': |
3.在第一次请求的时候执行
使用 before_first_request
这个钩子,把执行放在 Flask 第一次收到请求的时候。这就避免了2次初始化的干扰。
1 |
|
控制上传文件的大小
1 | from flask import Flask, Request |
为什么Gunicorn 和 Nginx 一起使用
Nginx功能强大,使用Nginx有诸多好处,但用Nginx转发Gunicorn服务,重点是解决“慢客户端行为”给服务器带来的性能降低问题;另外,在互联网上部署HTTP服务时,还要考虑的“快客户端响应”、SSL处理和高并发等问题,而这些问题在Nginx上一并能搞定,所以在Gunicorn服务之上加一层Nginx反向代理,是个一举多得的部署方案。
Gunicorn 是一个pre-forking (会通过预先开启大量的进程,等待并处理接到的请求。由于采用了这种方式来开启进程,服务器并不需要等待新的进程启动而消耗时间,因而能够以更快的速度应付多用户请求。) 的软件,这类软件对低延迟的通信,如负载均衡或服务间的互相通信,是非常有效的。但pre-forking系统的不足是,每个通信都会独占一个进程,当向服务器发出的请求多于服务器可用的进程时,由于服务器端没有更多进程响应新的请求,其响应效率会降低。
所以把Nginx挡在pre-forking服务前面处理请求是一种很好的选择。Nginx能够异步、高并发的响应客户端request(慢客户端请求对Nginx影响不大),Nginx一旦接收到的请求后立刻转给Gunicorn服务处理,处理结果再由Nginx以response的形式发回给客户端。这样,整个服务端和客户端的通信,就由原来仅通过Gunicorn的同步通信,变成了基于Nginx和Gunicorn的异步通信,通信效率和并发能力得到大大提升。
sqlalchemy 实现时间列自动更新
1 | class MonitorData(Base): |